动画和过渡
Scripting 通过 Observable / useObservable、Animation、Transition、withAnimation 以及视图的 animation / transition 属性,基本对齐了 SwiftUI 的动画能力,包括:
- 属性动画:数值、颜色、布局等属性随状态变化平滑过渡
- 过渡动画:视图插入 / 移除时的进出效果(如淡入淡出、滑入滑出、翻转)
- 显式动画:通过
withAnimation包裹一段「状态更新代码」统一加动画
Animation 类
Animation 用来描述「属性变化的时间曲线与节奏」,类似 SwiftUI 的 Animation。
工厂方法(创建动画)
Animation.default()
- 创建一个默认动画(通常是系统预设的 ease-in-out 曲线)
- 无需配置,适合「只想要一个普通的过渡效果」的场景
示例:
Animation.linear(duration?)
- 匀速动画,整段时间内速度保持恒定
duration:动画持续时间(秒),可选,不传时使用默认时长
适合:进度条数值增长、颜色线性变化等。
Animation.easeIn(duration?)
- 开始慢、后面加速
- 适合:元素「加速进入」的感觉
Animation.easeOut(duration?)
- 开始快、结尾慢
- 适合:元素「减速停止」的感觉,如卡片滑入后停在目标位置
Animation.bouncy(options?)
-
带回弹效果的动画
-
参数:
duration:总时长(秒)extraBounce:额外弹性,越大越明显
适合:按钮点击放大回弹、卡片弹出等「有趣」的动效。
Animation.smooth(options?)
- 相对柔和、过渡自然的动画
- 与
bouncy相比,弹性感更弱,更偏「丝滑」
Animation.snappy(options?)
- 动作「干脆利落」,响应速度快
- 常见于触控反馈、选中高亮等瞬间反馈场景
Animation.spring(options?)
支持两种配置方式(注意互斥):
-
基于时长的弹簧动画
duration: 动画持续时间bounce: 弹性大小
-
物理参数模式
response: 响应速度(值越小反馈越快)dampingFraction: 阻尼系数(0~1,越大越「稳」,越小越「弹」)
额外参数:
blendDuration:动画混合时长,用于多动画衔接场景(可选)
示例:
Animation.interactiveSpring(options?)
- 面向「交互驱动」的弹簧动画,例如拖拽结束后的回弹
- 参数与
spring的物理参数模式类似,语义更偏向手势交互
0 Animation.interpolatingSpring(options?)
两种配置方式(互斥):
-
物理参数模式
mass: 质量stiffness: 刚度damping: 阻尼initialVelocity: 初速度(可选)
-
时长 + 弹性模式
duration: 动画时长bounce: 弹性initialVelocity: 初速度(可选)
适合对动态效果「非常在意手感」的高级场景。
修改已有动画(链式 API)
delay(time)
- 使动画延迟
time秒后再开始 - 返回一个新的
Animation实例(原动画不变)
示例:
repeatCount(count, autoreverses?)
- 重复执行动画
count次 autoreverses(默认true):是否来回反向播放
示例:
repeatForever(autoreverses?)
- 无限次重复动画
- 适合加载动画、呼吸灯效果等
Animation 实战示例
示例 1:基本大小动画
Transition 类(视图过渡)
Transition 描述的是视图插入与移除时的「进场 / 退场效果」,对应 SwiftUI 的 AnyTransition。
注意:只有当视图在 JSX 中「存在与否」发生变化(如
{visible.value && <Text ... />})时,transition才会生效。
实例方法
animation(animation?)
- 为当前过渡指定(或覆盖)使用的
Animation - 不传时使用默认动画
示例:
combined(other)
- 组合两个过渡效果,类似 SwiftUI 的
.combined - 如:向下滑入 + 淡入
示例:
在视图中使用:
静态方法(构造不同类型的过渡)
Transition.identity()
- 「没有任何过渡」,视图插入 / 移除时不会做动画
- 通常用于禁用某些分支的过渡效果
Transition.move(edge)
- 从某个边缘移入 / 移出
edge通常是"leading" | "trailing" | "top" | "bottom"等(和 SwiftUI 对齐)
示例:
Transition.offset(position?)
- 通过偏移实现过渡
position:{ x: number, y: number },默认{ x: 0, y: 0 }
例如:
Transition.pushFrom(edge)
- 类似导航 push 的效果,从某个边缘推入并把旧内容推走
- 适合做「页面切换」类效果
Transition.opacity()
- 单纯的淡入 / 淡出
- 与
Animation搭配可以控制淡入淡出的节奏
Transition.scale(scale?, anchor?)
-
缩放过渡
-
scale:缩放比(默认 1) -
anchor:缩放基准点,支持:Point:如{ x: 0.5, y: 0.5 }KeywordPoint:如"center"、"top","bottom"等(具体值与 Scripting 内部对齐)
示例:
Transition.slide()
- 类似 SwiftUI 的
.slide,通常是从一侧滑入 / 滑出(具体方向由系统决定) - 常用于列表项、简单出现 / 消失效果
Transition.fade(duration?)
- 带时长配置的淡入 / 淡出
- 与
Transition.opacity()类似,但可以直接指定过渡时间
Flip 系列(翻转过渡)
- 类似卡片翻转的 3D 过渡
示例:
0 Transition.asymmetric(insertion, removal)
- 插入和移除使用不同的过渡效果
- 典型用法:进入时从下方滑入,离开时淡出
示例:
Transition 实战示例
示例:多种过渡效果对比
withAnimation:显式动画入口
withAnimation 用来「显式」地将一段状态更新包裹在动画上下文中,类似 SwiftUI 的 withAnimation。
它返回 Promise<void>,方便在异步逻辑中等待动画完成。
重载签名
-
第一个重载:使用默认动画
-
第二个重载:指定动画曲线 / 弹性等
-
第三个重载:额外指定完成条件:
"logicallyComplete":动画在时间轴上播放完成时视为完成(典型属性动画)"removed":通常用于涉及过渡的场景,等待相关视图被移出 / 动画结束后再继续逻辑(具体行为依赖底层 SwiftUI)
实际等待的精确时机由内部动画系统决定,一般可理解为「该动画相关的视图不再处于动画中」。
基本用法
默认动画
指定动画
在异步函数中等待动画结束
视图上的 animation / transition 属性
在 Scripting 的视图组件上,可以通过 props 的形式配置动画相关行为:
animation?: Animation(属性动画)transition?: Transition(插入 / 移除过渡)
属性动画(animation)
属性动画的核心逻辑:
- 当某个视图依赖的
Observable的value发生变化时 - 如果该视图设置了
animation={...}或更新发生在withAnimation中 - 则 SwiftUI 会对这些属性差异进行插值,从原值平滑过渡到新值
示例:
配合 withAnimation:
过渡动画(transition)
过渡动画只在「视图从无到有 / 从有到无」时生效。
关键点:
-
通常通过条件渲染控制:
-
状态变化本身需要动画上下文(
withAnimation或默认动画) -
Transition.animation(...)可为过渡指定特定Animation
示例:条件面板的进出过渡
综合示例:列表增删带过渡与属性动画
这个示例中:
- 使用
Observable<Item[]>作为列表数据源 transition负责列表项插入 / 删除时的滑动 + 淡入淡出withAnimation包裹增删操作,确保这些更新被动画化
